package com.anji.plus.gaea.job.trigger.service;

import com.anji.plus.gaea.job.core.constant.TriggerTypeEnum;
import com.anji.plus.gaea.job.core.dto.ReturnT;
import com.anji.plus.gaea.job.executor.util.XxlJobContext;
import com.anji.plus.gaea.job.trigger.dao.DaoService;
import com.anji.plus.gaea.job.trigger.dao.entity.MetaJobInfo;
import com.anji.plus.gaea.job.trigger.dao.entity.MetaJobLog;
import com.anji.plus.gaea.job.trigger.thread.JobTriggerPoolHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.MessageFormat;
import java.util.Date;

/**
 *
 * @author xuxueli 2020-10-30 20:43:10
 *
 * Borrowed from xxljob v2.4.0
 */
public class XxlJobCompleter {
    private static Logger logger = LoggerFactory.getLogger(XxlJobCompleter.class);


    /**
     * common fresh handle entrance (limit only once)
     *
     * @param xxlJobLog
     * @return
     */
    public static int updateHandleInfoAndFinish(MetaJobLog xxlJobLog) {

        // finish
        finishJob(xxlJobLog);

        // text最大64kb 避免长度过长
        if (xxlJobLog.getExecutorMsg().length() > 15000) {
            xxlJobLog.setExecutorMsg( xxlJobLog.getExecutorMsg().substring(0, 15000) );
        }

        //计算耗时
        timeCost(xxlJobLog);

        // fresh handle
        return DaoService.getInstance().updateMetaJobLogById(xxlJobLog);
    }

    private static void timeCost(MetaJobLog metaJobLog){
        if(metaJobLog == null || metaJobLog.getExecutorTime() == null || metaJobLog.getTriggerTime() == null){
            metaJobLog.setTimeCost(0L);
            return;
        }
        long start = metaJobLog.getTriggerTime().getTime();// 触发开始时间
        long end = metaJobLog.getExecutorTime().getTime();// 执行结束时间
        long cost = end - start;
        metaJobLog.setTimeCost(cost);
    }

    /**
     * do somethind to finish job
     */
    private static void finishJob(MetaJobLog xxlJobLog){

        // 1、handle success, to trigger child job
        String triggerChildMsg = null;
        if (XxlJobContext.HANDLE_CODE_SUCCESS == xxlJobLog.getExecutorStatus()) {

            MetaJobInfo xxlJobInfo = DaoService.getInstance().queryMetaJobInfoById(xxlJobLog.getJobId());
            if (xxlJobInfo!=null && xxlJobInfo.getChildJobIds()!=null && xxlJobInfo.getChildJobIds().trim().length()>0) {
                triggerChildMsg = "<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>触发子任务<<<<<<<<<<< </span><br>";

                String[] childJobIds = xxlJobInfo.getChildJobIds().split(",");
                for (int i = 0; i < childJobIds.length; i++) {
                    int childJobId = (childJobIds[i]!=null && childJobIds[i].trim().length()>0 && isNumeric(childJobIds[i]))?Integer.valueOf(childJobIds[i]):-1;
                    if (childJobId > 0) {

                        JobTriggerPoolHelper.trigger(childJobId, TriggerTypeEnum.PARENT, -1, null, null, null);
                        ReturnT<String> triggerChildResult = ReturnT.SUCCESS;

                        // add msg
                        triggerChildMsg += MessageFormat.format("{0}/{1} [任务ID={2}], 触发{3}, 触发备注: {4} <br>",
                                (i+1),
                                childJobIds.length,
                                childJobIds[i],
                                (triggerChildResult.getCode()==ReturnT.SUCCESS_CODE?"成功":"失败"),
                                triggerChildResult.getMsg());
                    } else {
                        triggerChildMsg += MessageFormat.format("{0}/{1} [任务ID={2}], 触发失败, 触发备注: 任务ID格式错误 <br>",
                                (i+1),
                                childJobIds.length,
                                childJobIds[i]);
                    }
                }

            }
        }

        if (triggerChildMsg != null) {
            xxlJobLog.setExecutorMsg( xxlJobLog.getExecutorMsg() + triggerChildMsg );
        }

        // 2、fix_delay trigger next
        // on the way

    }

    private static boolean isNumeric(String str){
        try {
            int result = Integer.valueOf(str);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

}
